﻿using Microsoft.AspNetCore.Http;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading;
using WebLog.Db;

namespace WebLog
{
    static class Comm
    {
        internal static string GetLinkStrByPath(string path)
            => $"\r\n<a href=\"http://192.168.40.2:9076/WebLog/WebLogIndex?uri={path}\">内网跳转</a>\r\n<a href=\"http://36.26.51.30:9076/weblog/WebLogIndex?uri={path}\">外网跳转</a>";
        internal static T GetPropertiesByRequest<T>(HttpRequest request, string name, string type, Action<object> setVal)
        {
            T result = default(T);
            string val = "";
            if (type == "Query" || type == "Form")
            {
                if (request.Query.ContainsKey(name))
                    val = request.Query[name].ToString();
                else if (request.Method.ToLower() == "post")
                {
                    try
                    {
                        if (request.Form.ContainsKey(name))
                            val = request.Form[name].ToString();
                    }
                    catch (Exception ex)
                    {
                    }
                }
            }
            if (val.IsNullEmpty()) return result;
            var elType = Nullable.GetUnderlyingType(typeof(T)) ?? typeof(T);//得到属性类型
            if (elType.IsEnum) result = (T)Enum.Parse(elType, val);//暂时用的是string文本转换枚举
            else result = (T)Convert.ChangeType(val, elType);
            setVal?.Invoke(result);//直接通过回调设置值
            return result;
        }
        internal static T GetDtoByRequest<T>(this HttpRequest request, string type, T obj)
        {
            if (type == "Body")
            {
                //request.EnableRewind();
                using (var requestReader = new System.IO.StreamReader(request.Body))
                {
                    var requestContent = requestReader.ReadToEndAsync().Result;
                    try
                    {
                        return JsonConvert.DeserializeObject<T>(requestContent);
                    }
                    catch (Exception)
                    {
                    }
                    return default(T);
                }
                //暂未适配
            }
            var list = typeof(T).GetProperties();
            var getpm = typeof(Comm).GetMethod("GetPropertiesByRequest", System.Reflection.BindingFlags.NonPublic
                    | System.Reflection.BindingFlags.Static);

            foreach (var el in list)
            {
                System.Reflection.MethodInfo curMethod = getpm.MakeGenericMethod(el.PropertyType);
                curMethod.Invoke(curMethod, new object[] { request, el.Name, type,
                    new Action<object>((val) => el.SetValue(obj, val, null)) });
            }
            return obj;
        }

        /// <summary>
        /// 将对象转换为字符串类型，如果对象是null则转换为string.Empty
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static string ToStringOrEmpty(this object value)
        {
            return value == null ? string.Empty : value.ToString();
        }
        /// <summary>
        /// 正则判断是否为Guid
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        public static bool IsGuidByReg(this object value)
        {
            if (value == null)
                return false;
            Regex reg = new Regex(@"^(\{{0,1}([0-9a-fA-F]){8}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){4}-([0-9a-fA-F]){12}\}{0,1})$");
            if (reg.IsMatch(value.ToStringOrEmpty()))
            {
                if (Guid.Empty != Guid.Parse(value.ToString()))
                    return true;
            }
            return false;
        }
        /// <summary>
        /// 判断对象是否为null, string.Empty 或空白字符
        /// </summary>
        /// <param name="value"></param>
        /// <returns></returns>
        internal static bool IsNullEmpty(this object value)
        {
            if ((value != null) && !(value.ToString() == string.Empty))
            {
                return (value.ToString().Trim().Length == 0);
            }
            return true;
        }
        internal static object[] GetEnumData(this Type enumType)
        {
            if (enumType.IsEnum)//枚举类型
            {
                var names = Enum.GetNames(enumType);
                object[] datas = new object[names.Length];
                var enumerator = Enum.GetValues(enumType).GetEnumerator();
                var values = new List<object> { };
                while (enumerator.MoveNext())
                    values.Add(enumerator.Current);
                Type type = enumType;   //获取类型
                for (int i = 0; i < names.Length; i++)
                {
                    var memberInfos = type.GetMember(names[i].ToString());
                    if (memberInfos != null && memberInfos.Length > 0)
                    {
                        var attrs = memberInfos[0].GetCustomAttributes(typeof(System.ComponentModel.DescriptionAttribute), false) as System.ComponentModel.DescriptionAttribute[];   //获取描述特性
                        if (attrs != null && attrs.Length > 0 && !attrs[0].Description.IsNullEmpty())
                            names[i] = attrs[0].Description;//使用枚举描述
                    }
                    datas[i] = new { id = values[i], text = names[i] };
                }
                return datas;
            }
            return null;
        }
        /// <summary>
        /// 使用自旋执行Action
        /// </summary>
        /// <param name="signal">信号量 （0的时候为可执行，1的时候不可执行）</param>
        /// <param name="action"></param>
        public static void RunActionBySignal(ref int signal, Action action)
        {
            if (action == null) return;
            while (System.Threading.Interlocked.Exchange(ref signal, 1) != 0) ;//加自旋锁
            action();
            System.Threading.Interlocked.Exchange(ref signal, 0);  //释放锁
        }

        internal static ITypeFactory TypeFactory = new DefaultTypeFactory();
        internal static SysLogHelper sysLogHelper { get => SysLogHelper.GetInstance(); }
        internal static SQLiteHelper sqliteHelper { get => SQLiteHelper.GetInstance(); }
        internal static KeyValueRepository repository { get => KeyValueRepository.GetInstance(); }
        public static string MainThreadName { get => "MainThread"; }
        public static bool IsMainThread(Thread t = null)
        {
            t = t ?? Thread.CurrentThread;
            return t.Name == MainThreadName;
        }
        /// <summary>
        /// 执行任务 同时包裹try语块
        /// </summary>
        /// <param name="action"></param>
        /// <param name="exCall"></param>
        internal static void TryRun(Action action, Action<Exception> exCall = null)
        {
            if (action != null)
                try
                {
                    action();
                }
                catch (Exception ex)
                {
                    if (exCall != null) exCall(ex);
                }
        }
    }

}
